package com.annotation.core;

import java.io.File;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class AnnotationListener implements ServletContextListener{
	private ServletContext context;
	
	@SuppressWarnings("unchecked")
	@Override
	public void contextInitialized(ServletContextEvent event) {
		System.out.println(getClass()+" listener init started");
		context= event.getServletContext();
		String path = context.getRealPath("")+context.getInitParameter("struts");
		SAXReader reader = new SAXReader();
		Map<String, String> map = new HashMap<String, String>();
		try {
			Document doc = reader.read(new File(path));
			Element root = doc.getRootElement();
			Element e = root.element("search");
			String[] packages = e.attributeValue("package").split(",");
			List<Class> list = new ArrayList<Class>();
			String classpath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
			//获取要扫描的包
			for(String pack : packages){
				File file = new File(classpath+pack.replace(".","/"));
				File[] files = file.listFiles();
				for(File f : files){
					if(!f.isDirectory()){
						try {
							String fname = f.getName().substring(0, f.getName().lastIndexOf("."));
							//返回扫描的包里的所有文件的全路径
							list.add(Class.forName(pack+"."+fname));
						} catch (ClassNotFoundException ex) {
							ex.printStackTrace();
						}
					}
				}
			}
			//循环包里的所有文件反射类
			for(Class clazz : list){
				Mapping req_class = (Mapping) clazz.getAnnotation(Mapping.class);
				Method[] methods = clazz.getMethods();
				//获取所有的反射方法
				for(Method method : methods){
					Mapping req = method.getAnnotation(Mapping.class);						
					if(req!=null){
						StringBuffer paraNames = new StringBuffer();
						//获取方法的参数列表
						for(Class para : method.getParameterTypes()){
							paraNames.append(","+para.getName());
							System.out.println(paraNames.toString());
						}
						String url = req.value();
						map.put(req_class.value()+url+".do", clazz.getName()+"||"+method.getName()+"||"+paraNames.substring(1));
					}
				}
			}
		} catch (Exception e1) {
			e1.printStackTrace();
		}
		context.setAttribute("struts", map);
		System.out.println(getClass()+" listener init finished.");
	}
	
	@Override
	public void contextDestroyed(ServletContextEvent e) {
		System.out.println(getClass()+" listener destroy finished.");
	}
}
